;;; init.el --- load the full configuration
;;; Commentary:

;; This file contains all config for my Emacs

;;; Code:

;; @see https://github.com/moscribe/emacs.d
;; @see https://github.com/seagle0128/.emacs.d
;; @see https://github.com/purcell/emacs.d

;;;;;;;;;;;;;;;;;;;;;;;
;;;; Initialize
;;;;;;;;;;;;;;;;;;;;;;;
(defvar default-package-mirror '(("melpa" . "https://melpa.org/packages/")
                                 ("org" . "https://orgmode.org/elpa/")
                                 ("gnu" . "https://elpa.gnu.org/packages/")))
(defvar emacs-china-package-mirror '(("gnu"   . "http://elpa.emacs-china.org/gnu/")
                                     ("melpa" . "http://elpa.emacs-china.org/melpa/")
                                     ("org"   . "http://elpa.emacs-china.org/org/")))
(defvar tuna-package-mirror '(("gnu"   . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
			                  ("melpa" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")
			                  ("org"   . "http://mirrors.tuna.tsinghua.edu.cn/elpa/org/")))

(defvar user/emacs-min-version "26"
  "User defined Use Emacs min Version.")
(defvar user/package-mirror tuna-package-mirror)
(defvar user/enable-benchmark-init nil)
(defvar user/normal-gc-cons-threshold (* 20 1024 1024))
(defvar user/init-gc-cons-threshold (* 128 1024 1024))
(defconst *is-mac* (eq system-type 'darwin))
(defconst *is-win64* (eq system-type 'windows-nt))
(defconst *is-linux* (or (eq system-type 'gnu/linux) (eq system-type 'linux)))

(when (version< emacs-version user/emacs-min-version)
  (error "Emacs %s or higher is required" user/emacs-min-version))

;; Speed up startup
(setq auto-mode-case-fold nil)

;; Load path
;; Optimize: Force "lisp"" and "elisp" at the head to reduce the startup time.
(defun update-load-path (&rest _)
  "Update `load-path'."
  (dolist (dir '("elisp" "lisp"))
    (push (expand-file-name dir user-emacs-directory) load-path)))

(advice-add #'package-initialize :after #'update-load-path)
(update-load-path)

;; adjust garbage collection thresholds during startup, and thereafter
(setq file-name-handler-alist nil)
(setq gc-cons-threshold user/init-gc-cons-threshold)
(add-hook 'emacs-startup-hook
          (lambda () (setq gc-cons-threshold user/normal-gc-cons-threshold)))

;; custome-file
(setq custom-file (expand-file-name ".cache/custom.el" user-emacs-directory))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; package
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq package-archives user/package-mirror)
(setq package-enable-at-startup nil)
(package-initialize) ;; 初始化

;; use-package installtion
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

(require 'use-package)
(setq use-package-always-ensure t)

(use-package quelpa)
(use-package quelpa-use-package)

;; exec-path-from-shell
(use-package exec-path-from-shell
  :if (or *is-mac* *is-linux*)
  :init (exec-path-from-shell-initialize)
  :config (exec-path-from-shell-copy-envs
           '("WORKON_HOME"
             "VIRTUALENVWARPPER_PYTHON"
             "VIRTUALENVWRAPPER_VIRTUALENV")))

;; auto-package-update
(use-package auto-package-update
  :defer t
  :init
  (setq auto-package-update-delete-old-versions t
        auto-package-update-hide-results t)
  (defalias 'upgrade-packages #'auto-package-update-now))

;; restart-emcas
(use-package restart-emacs
  :defer t)

;; posframe
(use-package posframe
  :defer t)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; benchmark
;;;;;;;;;;;;;;;;;;;;;;;;;
(when user/enable-benchmark-init
  (define-advice define-obsolete-function-alias (:filter-args (ll) fix-obsolete)
    (let ((obsolete-name (pop ll))
          (current-name (pop ll))
          (when (if ll (pop ll) "1"))
          (docstring (if ll (pop ll) nil)))
      (list obsolete-name current-name when docstring)))
  ;; benchmark
  (use-package benchmark-init
    :hook (after-init . benchmark-init/deactivate)
    :init (benchmark-init/activate)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; require pkgs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(require 'init-basic)
(require 'init-function)
(require 'init-edit)
(require 'init-ui)
(require 'init-evil)
(require 'init-prog)
(require 'init-selectrum)
(require 'init-dired)
(require 'init-company)
(require 'init-flycheck)
(require 'init-eglot)
(require 'init-git)
(require 'init-org)
(require 'init-docker)
(require 'init-zig)
(require 'init-erlang)
(require 'init-dart)
(require 'init-lisp)
(require 'init-cc)
(require 'init-go)
(require 'init-rust)
(require 'init-lua)
(require 'init-python)
(require 'init-ts)
(require 'init-yasnippet)
(require 'init-binding)

;;; init.el ends here
